<template>
	<div ref="container" class="preview-3d"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { AStarFinder, Grid, Heuristic } from "pathfinding";

export default {
	props: {
		features: { type: Array, required: true },
		height: { type: Number, default: 8 },
		gridSize: { type: Number, default: 5 }, // 网格大小，需为正数
	},
	data() {
		return {
			scene: null,
			camera: null,
			renderer: null,
			controls: null,
			rooms: [],
			roads: [],
			// 新增地板数组
			floors: [],
			startPoint: null,
			endPoint: null,
			path: null,
			grid: null,
			gridWidth: 0,
			gridHeight: 0,
			finder: null,
			pathGeometry: null,
			pathMaterial: null,
			pathMesh: null,
			previousPathNodes: [], // 存储上一次路径经过的节点
			isPathCalculated: false, // 标记是否已计算过路径
		};
	},
	mounted() {
		this.init3D();
		this.createBuildings();
		this.initPathfinder(); // 初始化寻路器
		this.animate();
		this.$refs.container.addEventListener("click", this.onMouseClick);
	},
	methods: {
		init3D() {
			this.scene = new THREE.Scene();
			this.scene.background = new THREE.Color(0xffffff);

			this.camera = new THREE.PerspectiveCamera(
				75,
				this.$refs.container.clientWidth /
				this.$refs.container.clientHeight,
				0.1,
				1000
			);
			this.camera.position.set(0, 100, 150);

			this.renderer = new THREE.WebGLRenderer({ antialias: true });
			this.renderer.setSize(
				this.$refs.container.clientWidth,
				this.$refs.container.clientHeight
			);
			this.$refs.container.appendChild(this.renderer.domElement);

			this.controls = new OrbitControls(
				this.camera,
				this.renderer.domElement
			);
			this.controls.mouseButtons = {
				LEFT: this.controls.mouseButtons.RIGHT,
				RIGHT: this.controls.mouseButtons.LEFT,
			};
			this.controls.screenSpacePanning = false;
			this.controls.enableDamping = true;
			this.controls.minPolarAngle = 0;
			this.controls.maxPolarAngle = Math.PI / 2;

			this.scene.add(new THREE.AmbientLight(0xffffff, 0.5));

			const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
			directionalLight.position.set(10, 10, 10);
			this.scene.add(directionalLight);
		},
		initPathfinder() {
			// 初始化A*寻路器
			this.finder = new AStarFinder({
				diagonalMovement: 2, // 允许8方向移动
				// heuristic: Heuristic.euclidean, // 改为欧几里得距离更适合3D场景
				biDirectional: true, // 暂时禁用双向搜索便于调试
				allowDiagonal: true,
				dontCrossCorners: true,
				weight: 1.5, // 增加权重帮助找到更优路径
				trackRecursion: true, //是否跟踪递归调用（调试用）
			});
		},
		createBuildings() {
			// 原有创建建筑代码...
			let allCoordinates = [];
			// 重置地板数组
			this.floors = [];
			this.features.forEach((feature) => {
				if (
					feature.layerType !== "path" &&
					feature.coordinates &&
					feature.coordinates[0] &&
					Array.isArray(feature.coordinates[0])
				) {
					allCoordinates = allCoordinates.concat(
						this.filterValidCoordinates(feature.coordinates[0])
					);
				}
			});

			let centerX = 112.45,
				centerY = 37.75;
			if (allCoordinates.length > 0) {
				const xs = allCoordinates
					.map((coord) => coord[0])
					.filter((x) => !isNaN(x));
				const ys = allCoordinates
					.map((coord) => coord[1])
					.filter((y) => !isNaN(y));

				if (xs.length > 0 && ys.length > 0) {
					centerX = (Math.min(...xs) + Math.max(...xs)) / 2;
					centerY = (Math.min(...ys) + Math.max(...ys)) / 2;
				}
			}

			this.features.forEach((feature) => {
				if (!feature.coordinates || !feature.coordinates[0]) {
					console.warn("特征缺少坐标数据:", feature);
					return;
				}

				if (feature.layerType === "floor") {
					// 保存地板对象到floors数组
					const floor = this.createFloor(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
					if (floor) this.floors.push(floor);
				} else if (feature.layerType === "room") {
					this.createRoom(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
				} else if (feature.layerType === "road") {
					this.createRoad(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
				}
			});

			// 构建导航网格
			this.buildNavigationGrid(centerX, centerY);
		},
		buildNavigationGrid(centerX, centerY) {
			// 收集所有地板的边界用于构建导航网格
			if (!this.floors || this.floors.length === 0) return;

			let minX = Infinity,
				minY = Infinity;
			let maxX = -Infinity,
				maxY = -Infinity;

			// 计算地板场景边界
			this.floors.forEach((floor) => {
				const box = new THREE.Box3().setFromObject(floor);
				const min = box.min;
				const max = box.max;

				if (min.x < minX) minX = min.x;
				if (min.z < minY) minY = min.z;
				if (max.x > maxX) maxX = max.x;
				if (max.z > maxY) maxY = max.z;
			});

			// 扩展边界以包含整个地板场景
			const padding = 20; // 适当减小padding，使网格更贴近地板
			minX -= padding;
			minY -= padding;
			maxX += padding;
			maxY += padding;

			// 计算网格尺寸（基于地板边界）
			this.gridWidth = Math.ceil((maxX - minX) / this.gridSize);
			this.gridHeight = Math.ceil((maxY - minY) / this.gridSize);

			// 创建pathfinding库所需的Grid对象
			this.grid = new Grid(this.gridWidth, this.gridHeight);

			// 标记障碍物（包括房间和地板上的其他物体）
			this.markObstacles(minX, minY);

			// 可视化网格（调试用），确保在标记障碍物后执行
			// this.visualizeGrid(minX, minY, maxX, maxY);

			console.log(
				`导航网格构建完成: ${this.gridWidth}x${this.gridHeight}`
			);
		},
		visualizeGrid(minX, minY, maxX, maxY) {
			// 移除旧的网格可视化
			if (this.gridVisualization) {
				this.scene.remove(this.gridVisualization);
			}

			const geometry = new THREE.BufferGeometry();
			const vertices = [];
			const lineColor = 0xcccccc;

			// 根据实际网格尺寸绘制网格线
			for (let y = 0; y <= this.gridHeight; y++) {
				const z = minY + y * this.gridSize;
				vertices.push(minX, 0, z); // 左边界
				vertices.push(maxX, 0, z); // 右边界
			}

			for (let x = 0; x <= this.gridWidth; x++) {
				const xPos = minX + x * this.gridSize;
				vertices.push(xPos, 0, minY); // 下边界
				vertices.push(xPos, 0, maxY); // 上边界
			}

			geometry.setAttribute(
				"position",
				new THREE.Float32BufferAttribute(vertices, 3)
			);

			const material = new THREE.LineBasicMaterial({
				color: lineColor,
				transparent: true,
				opacity: 0.3,
				linewidth: 1,
			});

			this.gridVisualization = new THREE.LineSegments(geometry, material);
			this.scene.add(this.gridVisualization);

			// 标记网格原点和角落
			// this.addGridMarkers(minX, minY, maxX, maxY);
		},
		addGridMarkers(minX, minY, maxX, maxY) {
			// 添加网格原点标记
			const origin = new THREE.Mesh(
				new THREE.SphereGeometry(2, 16, 16),
				new THREE.MeshBasicMaterial({ color: 0xff0000 })
			);
			origin.position.set(minX, 1, minY);
			this.scene.add(origin);

			// 添加网格右上角标记
			const corner = new THREE.Mesh(
				new THREE.SphereGeometry(2, 16, 16),
				new THREE.MeshBasicMaterial({ color: 0x00ff00 })
			);
			corner.position.set(maxX, 1, maxY);
			this.scene.add(corner);
		},

		markObstacles(globalMinX, globalMinY) {
			// 标记房间为障碍物
			this.rooms.forEach((room) => {
				const box = new THREE.Box3().setFromObject(room);
				this.markObstacleInGrid(box, globalMinX, globalMinY);
			});

			// 标记其他障碍物（如道路边缘）
			this.roads.forEach((road) => {
				const box = new THREE.Box3().setFromObject(road);
				this.markObstacleInGrid(box, globalMinX, globalMinY);
			});
		},
		getGroundY() {
			// 获取地板的Y坐标（假设地板在最低层）
			if (this.floors.length === 0) return 0;

			let minY = Infinity;
			this.floors.forEach((floor) => {
				const box = new THREE.Box3().setFromObject(floor);
				if (box.min.y < minY) minY = box.min.y;
			});
			return minY;
		},
		markObstacleInGrid(box, globalMinX, globalMinY) {
			// 仅标记地面层的障碍物（Y轴限制）
			const boxMin = box.min.clone();
			const boxMax = box.max.clone();
			const groundY = this.getGroundY();
			boxMin.y = groundY;
			boxMax.y = groundY + 2; // 仅标记地面以上2单位的区域

			// 计算3D坐标到网格坐标的转换
			const xRatio = 1 / this.gridSize;
			const zRatio = 1 / this.gridSize;

			const gridMinX = Math.floor((boxMin.x - globalMinX) * xRatio);
			const gridMinY = Math.floor((boxMin.z - globalMinY) * zRatio);
			const gridMaxX = Math.ceil((boxMax.x - globalMinX) * xRatio);
			const gridMaxY = Math.ceil((boxMax.z - globalMinY) * zRatio);

			// 确保坐标在网格范围内
			const buffer = 1; // 障碍物外扩1格
			const safeGridMinX = Math.max(0, gridMinX - buffer);
			const safeGridMinY = Math.max(0, gridMinY - buffer);
			const safeGridMaxX = Math.min(
				this.gridWidth - 1,
				gridMaxX + buffer
			);
			const safeGridMaxY = Math.min(
				this.gridHeight - 1,
				gridMaxY + buffer
			);

			// 标记为障碍物
			for (let x = safeGridMinX; x <= safeGridMaxX; x++) {
				for (let y = safeGridMinY; y <= safeGridMaxY; y++) {
					if (
						x >= 0 &&
						x < this.gridWidth &&
						y >= 0 &&
						y < this.gridHeight
					) {
						this.grid.setWalkableAt(x, y, false);
					}
				}
			}
		},

		markObstaclesInGrid(box, minX, minY) {
			// 将3D边界框转换为网格中的障碍物
			const min = box.min;
			const max = box.max;

			// 转换为网格坐标
			const gridMinX = Math.floor((min.x - minX) / this.gridSize);
			const gridMinY = Math.floor((min.z - minY) / this.gridSize);
			const gridMaxX = Math.ceil((max.x - minX) / this.gridSize);
			const gridMaxY = Math.ceil((max.z - minY) / this.gridSize);

			// 确保坐标在网格范围内
			const buffer = 1;
			const clampedMinX = Math.max(0, gridMinX + buffer);
			const clampedMinY = Math.max(0, gridMinY + buffer);
			const clampedMaxX = Math.min(this.gridWidth - 1, gridMaxX - buffer);
			const clampedMaxY = Math.min(
				this.gridHeight - 1,
				gridMaxY - buffer
			);

			// 标记为障碍物
			for (let x = clampedMinX; x <= clampedMaxX; x++) {
				for (let y = clampedMinY; y <= clampedMaxY; y++) {
					const node = this.grid.getNodeAt(x, y);
					if (node) node.walkable = false;
				}
			}
		},

		createRoom(coordinates, centerX, centerY, height) {
			// 原有创建房间代码...
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("房间坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			if (!this.isValidShape(points)) {
				console.warn("房间形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复房间形状，跳过创建");
					return;
				}
			}

			const shape = new THREE.Shape(points);
			const roomHeight = height;

			const geometry = new THREE.ExtrudeGeometry(shape, {
				depth: roomHeight,
				bevelEnabled: true,
				curveSegments: 1,
				steps: 1,
			});

			if (!this.validateGeometry(geometry)) {
				console.error("房间几何体无效，跳过创建");
				return;
			}

			const material = new THREE.MeshLambertMaterial({
				color: 0x87ceeb,
				side: THREE.DoubleSide,
				transparent: false,
				opacity: 0.5,
			});

			const room = new THREE.Mesh(geometry, material);
			room.rotation.x = -Math.PI / 2;
			room.position.y = -height + 1;
			room.userData = {
				originalColor: 0x87ceeb,
				type: "room",
				centerX: centerX,
				centerY: centerY,
			};

			this.rooms.push(room);
			this.scene.add(room);

			// 添加顶面边缘蓝色周长线
			const linePoints = points.map(
				(p) => new THREE.Vector3(p.x, p.y, roomHeight)
			);
			if (
				points.length > 0 &&
				!points[0].equals(points[points.length - 1])
			) {
				linePoints.push(
					new THREE.Vector3(points[0].x, points[0].y, roomHeight)
				);
			}

			if (linePoints.length >= 2) {
				const lineGeometry = new THREE.BufferGeometry().setFromPoints(
					linePoints
				);
				const lineMaterial = new THREE.LineBasicMaterial({
					color: 0x0000ff,
					linewidth: 5,
					transparent: false,
					depthTest: true,
					depthWrite: true,
				});

				const perimeterLine = new THREE.Line(
					lineGeometry,
					lineMaterial
				);
				perimeterLine.rotation.x = -Math.PI / 2;
				perimeterLine.position.y = -height + 1.2;
				perimeterLine.updateMatrix();
				this.scene.add(perimeterLine);
			} else {
				console.warn(
					"无法创建房间周长线，点数量不足:",
					linePoints.length
				);
			}
		},
		createRoad(coordinates, centerX, centerY, height) {
			// 过滤无效坐标点
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("道路坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			// 创建点集合
			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			// 验证并修复自相交的形状
			if (!this.isValidShape(points)) {
				console.warn("道路形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复道路形状，跳过创建");
					return;
				}
			}

			// 创建道路形状
			const shape = new THREE.Shape(points);
			const geometry = new THREE.ShapeGeometry(shape);

			// 验证几何体
			if (!this.validateGeometry(geometry)) {
				console.error("道路几何体无效，跳过创建");
				return;
			}

			// 创建材质和网格
			const material = new THREE.MeshBasicMaterial({
				color: 0x999999,
				transparent: true,
				opacity: 0.8,
			});

			const road = new THREE.Mesh(geometry, material);
			road.rotation.x = -Math.PI / 2;
			road.position.y = 0.1;
			road.userData = {
				type: "road",
				shape: shape,
				points: points,
			};

			this.roads.push(road);
			this.scene.add(road);
		},
		createFloor(coordinates, centerX, centerY, height) {
			// 过滤无效坐标点
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("楼板坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			// 创建点集合
			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			// 验证并修复自相交的形状
			if (!this.isValidShape(points)) {
				console.warn("楼板形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复楼板形状，跳过创建");
					return;
				}
			}

			// 创建楼板形状
			const shape = new THREE.Shape(points);
			const slabThickness = 1;

			// 创建几何体
			const geometry = new THREE.ExtrudeGeometry(shape, {
				depth: slabThickness,
				bevelEnabled: true,
				curveSegments: 1,
				steps: 1,
			});

			// 验证几何体
			if (!this.validateGeometry(geometry)) {
				console.error("楼板几何体无效，跳过创建");
				return;
			}

			// 创建材质和网格
			const material = new THREE.MeshLambertMaterial({
				color: 0xf5f5f5,
				side: THREE.DoubleSide,
				transparent: false,
				opacity: 1.0,
			});

			const floorSlab = new THREE.Mesh(geometry, material);
			floorSlab.rotation.x = -Math.PI / 2;
			floorSlab.position.y = -height + slabThickness / 2;
			this.scene.add(floorSlab);
			return floorSlab;
		},

		// 过滤无效坐标点
		filterValidCoordinates(coordinates) {
			if (!Array.isArray(coordinates)) {
				console.warn("坐标数据不是数组:", coordinates);
				return [];
			}

			return coordinates.filter((coord) => {
				if (!Array.isArray(coord) || coord.length < 2) {
					console.warn("无效坐标点:", coord);
					return false;
				}

				// 检查坐标是否为有效数字
				if (isNaN(coord[0]) || isNaN(coord[1])) {
					console.warn("坐标包含NaN值:", coord);
					return false;
				}

				// 检查坐标是否为无穷大
				if (!isFinite(coord[0]) || !isFinite(coord[1])) {
					console.warn("坐标包含无穷大值:", coord);
					return false;
				}

				return true;
			});
		},
		// 验证形状有效性
		isValidShape(points) {
			return true;
			if (!Array.isArray(points) || points.length < 3) {
				return false;
			}

			// 检查是否有重复点
			for (let i = 0; i < points.length; i++) {
				for (let j = i + 1; j < points.length; j++) {
					if (points[i].equals(points[j])) {
						return false;
					}
				}
			}

			return true;
		},
		// 修复无效形状
		fixShape(points) {
			if (!Array.isArray(points)) return [];

			// 移除重复点
			const uniquePoints = [];
			points.forEach((point) => {
				if (!uniquePoints.some((p) => p.equals(point))) {
					uniquePoints.push(point);
				}
			});

			return uniquePoints;
		},
		// 验证几何体有效性
		validateGeometry(geometry) {
			if (
				!geometry ||
				!geometry.attributes ||
				!geometry.attributes.position
			) {
				return false;
			}

			const position = geometry.attributes.position;

			// 检查顶点数量
			if (position.count < 3) {
				console.warn("几何体顶点数量不足:", position.count);
				return false;
			}

			// 检查是否有NaN或无穷大值
			for (let i = 0; i < position.count; i++) {
				if (
					isNaN(position.getX(i)) ||
					isNaN(position.getY(i)) ||
					isNaN(position.getZ(i)) ||
					!isFinite(position.getX(i)) ||
					!isFinite(position.getY(i)) ||
					!isFinite(position.getZ(i))
				) {
					console.warn("几何体包含无效顶点数据，索引:", i);
					return false;
				}
			}

			return true;
		},

		onMouseClick(event) {
			if (!this.$refs.container) return;

			const rect = this.$refs.container.getBoundingClientRect();
			const mouse = new THREE.Vector2();
			mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
			mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

			const raycaster = new THREE.Raycaster();
			raycaster.setFromCamera(mouse, this.camera);

			if (!this.rooms || this.rooms.length === 0) return;

			const intersects = raycaster.intersectObjects(this.rooms);

			if (intersects.length > 0 && intersects[0].object) {
				const clickedRoom = intersects[0].object;

				// 重置所有房间颜色
				this.rooms.forEach((room) => {
					if (room && room.material && room.userData) {
						room.material.color.set(room.userData.originalColor);
					}
				});

				// 点击逻辑：设置起点、终点并进行路径规划
				if (!this.startPoint) {
					this.startPoint = clickedRoom;
					if (this.startPoint && this.startPoint.material) {
						this.startPoint.material.color.set(0x00ff00);
					}
					this.endPoint = null;
				} else if (!this.endPoint && clickedRoom !== this.startPoint) {
					this.endPoint = clickedRoom;
					if (this.endPoint && this.endPoint.material) {
						this.endPoint.material.color.set(0xff0000);
					}

					if (this.startPoint && this.endPoint) {
						this.calculatePath(); // 计算路径
					}
				} else {
					this.startPoint = clickedRoom;
					if (this.startPoint && this.startPoint.material) {
						this.startPoint.material.color.set(0x00ff00);
					}
					this.endPoint = null;
					this.clearPath(); // 清除现有路径
				}
			}
		},

		getRoomCenter(room) {
			if (!room) return null;

			const box = new THREE.Box3().setFromObject(room);
			return box.getCenter(new THREE.Vector3());
		},
		getGridMinX() {
			if (this.rooms.length === 0) return 0;

			const box = new THREE.Box3();
			this.rooms.forEach((room) =>
				box.union(new THREE.Box3().setFromObject(room))
			);
			return box.min.x;
		},

		getGridMinY() {
			if (this.rooms.length === 0) return 0;

			const box = new THREE.Box3();
			this.rooms.forEach((room) =>
				box.union(new THREE.Box3().setFromObject(room))
			);
			return box.min.z;
		},

		calculatePath() {
			if (!this.grid || !this.startPoint || !this.endPoint) return;

			// 清除现有路径并重置网格状态
			this.clearPath(true); // 传递true表示需要重置网格状态

			// 获取起点和终点的中心点
			const startCenter = this.getRoomCenter(this.startPoint);
			const endCenter = this.getRoomCenter(this.endPoint);

			if (!startCenter || !endCenter) return;

			// 将3D坐标转换为网格坐标
			const minX = this.getGridMinX();
			const minY = this.getGridMinY();

			const startGridX = Math.floor(
				(startCenter.x - minX) / this.gridSize
			);
			const startGridY = Math.floor(
				(startCenter.z - minY) / this.gridSize
			);

			const endGridX = Math.floor((endCenter.x - minX) / this.gridSize);
			const endGridY = Math.floor((endCenter.z - minY) / this.gridSize);

			// 确保坐标在网格范围内
			const clampedStartX = Math.max(
				0,
				Math.min(this.gridWidth - 1, startGridX)
			);
			const clampedStartY = Math.max(
				0,
				Math.min(this.gridHeight - 1, startGridY)
			);
			const clampedEndX = Math.max(
				0,
				Math.min(this.gridWidth - 1, endGridX)
			);
			const clampedEndY = Math.max(
				0,
				Math.min(this.gridHeight - 1, endGridY)
			);
			// 检查起点或终点是否在障碍物上
			const startNode = this.grid.getNodeAt(clampedStartX, clampedStartY);
			const endNode = this.grid.getNodeAt(clampedEndX, clampedEndY);
			console.log("===== 路径计算开始 =====");
			console.log("网格尺寸:", this.gridWidth, "x", this.gridHeight);
			console.log("起点网格坐标:", clampedStartX, clampedStartY);
			console.log("终点网格坐标:", clampedEndX, clampedEndY);
			console.log("网格尺寸:", this.gridWidth, "x", this.gridHeight);
			// console.log("网格范围 - X: ", minX, "到", maxX);
			// console.log("网格范围 - Z: ", minY, "到", maxY);
			console.log("网格单元大小:", this.gridSize);
			console.log(
				"起点是否可通行:",
				startNode ? startNode.walkable : false
			);
			console.log("终点是否可通行:", endNode ? endNode.walkable : false);
			if (
				!startNode ||
				!startNode.walkable ||
				!endNode ||
				!endNode.walkable
			) {
				console.error("起点或终点位于障碍物上，无法规划路径");
				return;
			}

			// 使用A*算法查找路径
			try {
				const grid = this.grid.clone();
				this.path = this.finder.findPath(
					clampedStartX,
					clampedStartY,
					clampedEndX,
					clampedEndY,
					grid
				);
				console.log(
					this.previousPathNodes,
					"previousPathNodes",
					clampedStartX,
					clampedStartY,
					clampedEndX,
					clampedEndY,
					grid
				);
				if (this.path.length > 0) {
					console.log("找到路径，节点数:", this.path.length);
					console.log("路径节点:", this.path);
				} else {
					console.log("未找到路径");
				}
				console.log("===== 路径计算结束 =====");
				if (this.path.length > 0) {
					// 路径找到，渲染路径并记录经过的节点
					this.renderPath(startCenter, endCenter, minX, minY);
					this.recordPathNodes(
						clampedStartX,
						clampedStartY,
						clampedEndX,
						clampedEndY
					);
					this.isPathCalculated = true;
				} else {
					console.warn("无法找到路径");
					this.showPathNotFoundIndicator();
					this.isPathCalculated = false;
				}
			} catch (error) {
				console.error("路径计算出错:", error);
				this.isPathCalculated = false;
			}
		},
		debugGridObstacles(startX, startY, endX, endY) {
			// 调试网格障碍物分布
			console.log("===== 网格障碍物分布 =====");
			const minX = Math.max(0, startX - 5);
			const minY = Math.max(0, startY - 5);
			const maxX = Math.min(this.gridWidth - 1, endX + 5);
			const maxY = Math.min(this.gridHeight - 1, endY + 5);

			for (let y = minY; y <= maxY; y++) {
				let row = "";
				for (let x = minX; x <= maxX; x++) {
					const node = this.grid.getNodeAt(x, y);
					if (x === startX && y === startY) row += "S";
					else if (x === endX && y === endY) row += "E";
					else if (node && !node.walkable) row += "■";
					else row += "□";
				}
				console.log(row);
			}
			console.log("===== 障碍物分布结束 =====");
		},
		renderPath(startCenter, endCenter, minX, minY) {
			if (!this.path || this.path.length === 0) return;

			const pathPoints = [startCenter.clone()];
			this.previousPathNodes = []; // 重置节点记录

			this.path.forEach((point, index) => {
				const x = minX + point[0] * this.gridSize + this.gridSize / 2;
				const z = minY + point[1] * this.gridSize + this.gridSize / 2;
				pathPoints.push(new THREE.Vector3(x, startCenter.y + 1, z));

				// 记录所有路径节点（除了起点和终点）
				if (index > 0 && index < this.path.length - 1) {
					this.previousPathNodes.push({ x: point[0], y: point[1] });
				}
			});

			pathPoints.push(endCenter.clone());

			// 创建路径几何体
			this.pathGeometry = new THREE.BufferGeometry().setFromPoints(
				pathPoints
			);

			// 创建路径材质
			this.pathMaterial = new THREE.LineBasicMaterial({
				color: 0xffd700, // 金色
				linewidth: 5,
				transparent: false,
				depthTest: true,
				depthWrite: true,
			});

			// 创建路径线段
			this.pathMesh = new THREE.Line(
				this.pathGeometry,
				this.pathMaterial
			);
			this.scene.add(this.pathMesh);
			// 可视化网格（调试用）
			this.visualizeGrid(minX, minY);
			console.log("路径渲染完成，点数:", pathPoints.length);
		},
		recordPathNodes(startX, startY, endX, endY) {
			// 记录路径经过的节点（不包括起点和终点）
			this.previousPathNodes = [];

			// 简化：这里假设path数组已经包含了中间节点
			// 实际应该根据this.path内容记录
			if (this.path && this.path.length > 2) {
				this.path.slice(1, -1).forEach((point) => {
					this.previousPathNodes.push({ x: point[0], y: point[1] });
				});
			}
		},

		clearPath(resetGrid = false) {
			// 清除现有路径
			if (this.pathMesh) {
				this.scene.remove(this.pathMesh);
				this.pathMesh = null;
			}

			if (this.pathGeometry) {
				this.pathGeometry.dispose();
				this.pathGeometry = null;
			}

			if (this.pathMaterial) {
				this.pathMaterial.dispose();
				this.pathMaterial = null;
			}

			this.path = null;
			this.previousPathNodes = [];

			// 重置网格状态（如果需要）
			if (resetGrid && this.grid && this.isPathCalculated) {
				this.resetGridState();
			}

			this.isPathCalculated = false;
		},
		resetGridState() {
			// 重置网格状态，恢复路径经过的节点为可通行
			this.previousPathNodes.forEach((node) => {
				const x = Math.max(0, Math.min(this.gridWidth - 1, node.x));
				const y = Math.max(0, Math.min(this.gridHeight - 1, node.y));
				const gridNode = this.grid.getNodeAt(x, y);
				if (gridNode) {
					gridNode.walkable = true; // 恢复为可通行
				}
			});

			console.log("网格状态已重置");
		},
		showPathNotFoundIndicator() {
			// 显示路径未找到的指示
			if (this.pathMesh) {
				this.scene.remove(this.pathMesh);
			}

			const geometry = new THREE.BufferGeometry().setFromPoints([
				new THREE.Vector3(0, 50, 0),
				new THREE.Vector3(0, 50, 0),
			]);

			const material = new THREE.LineBasicMaterial({
				color: 0xff0000,
				linewidth: 5,
			});

			const line = new THREE.Line(geometry, material);
			this.scene.add(line);

			// 短暂显示后移除
			setTimeout(() => {
				if (line.parent) {
					this.scene.remove(line);
				}
			}, 3000);
		},
		animate() {
			requestAnimationFrame(this.animate.bind(this));
			if (this.controls) this.controls.update();
			if (this.renderer && this.scene && this.camera) {
				this.renderer.render(this.scene, this.camera);
			}
		},
	},
	beforeUnmount() {
		// 清理资源
		if (this.$refs.container) {
			this.$refs.container.removeEventListener(
				"click",
				this.onMouseClick
			);
		}

		if (this.renderer) {
			this.renderer.dispose();
			if (this.$refs.container) {
				this.$refs.container.removeChild(this.renderer.domElement);
			}
		}

		if (this.controls) this.controls.dispose();
		this.clearPath();
	},
	watch: {
		features: {
			deep: true,
			handler() {
				// 特征变化时重新渲染
				if (!this.scene) return;

				this.scene.traverse((child) => {
					if (
						child instanceof THREE.Mesh &&
						child !== this.controls?.object &&
						!child.isCube
					) {
						this.scene.remove(child);
					}
				});

				this.rooms = [];
				this.roads = [];
				this.clearPath();

				this.createBuildings();
			},
		},
	},
};
</script>

<style scoped>
.preview-3d {
	width: 100%;
	height: 100%;
}
</style>
